package com.java.netty.server.vnc;

import com.java.netty.common.codec.VncDecoder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.AdaptiveRecvByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

public class StartServer {

   private static final int MAX_FRAME_LENGTH = 4096;
   private static final int LENGTH_FIELD_OFFSET = 4;
   private static final int LENGTH_FIELD_LENGTH = 4;

   public static void main(String[] args) {
      //java-netty-server为端口为40000
      int port = 40000;
      ServerBootstrap b = new ServerBootstrap();
      NioEventLoopGroup boss = new NioEventLoopGroup();
      NioEventLoopGroup worker = new NioEventLoopGroup();
      try {
         b.group(boss, worker);
         b.channel(NioServerSocketChannel.class);
         b.childHandler(new ChannelInitializer<Channel>() {
            @Override
            protected void initChannel(Channel channel) throws Exception {
               channel.pipeline().addLast(new LengthFieldBasedFrameDecoder(MAX_FRAME_LENGTH, LENGTH_FIELD_OFFSET, LENGTH_FIELD_LENGTH));
               channel.pipeline().addLast(new VncDecoder());
               channel.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
               channel.pipeline().addLast(new ServerHandler());
            }
         });

         b.option(ChannelOption.SO_BACKLOG, 1)
            //内存池
            .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
            //容量动态调整的接收缓冲区分配器
            .option(ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator.DEFAULT).childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT).childOption(ChannelOption.SO_KEEPALIVE, true);
         ChannelFuture f = b.bind(port);
         System.out.println("java-netty-server 端口：" + port + ",己启动监听中......");
         f.channel().closeFuture().sync();
      } catch (Exception e) {
         System.out.println("c2s启动异常");
      } finally {
         worker.shutdownGracefully();
         boss.shutdownGracefully();
      }
   }
}
